﻿using System.Net;
using System.Text;
using System.Threading.Channels;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace PasteCluster
{
    /// <summary>
    /// 注意用IOC单例注入系统，多处调用
    /// </summary>
    public class PasteClusterHandler : IDisposable
    {

        /// <summary>
        /// 
        /// </summary>
        private readonly IHttpClientFactory _httpClientFactory;

        /// <summary>
        /// 用于内部消息中转等 节点中的任务
        /// </summary>
        private Channel<PasteEventModel> _channel_slove;

        /// <summary>
        /// 业务队列 表示队列中的消息要业务逻辑处理，当前可能为slove也可能为master
        /// 业务监听队列
        /// 表示业务要处理的消息
        /// 当前节点可能是slove节点
        /// 也可能是master节点
        /// </summary>
        public Channel<PasteSloveMessage> ChannelCluster;

        /// <summary>
        /// 当前节点信息
        /// </summary>
        private PasteNodeModel _current_node = null;

        /// <summary>
        /// 当前的Master是哪个
        /// </summary>
        private PasteNodeModel _current_master = null;

        /// <summary>
        /// 
        /// </summary>
        private ILogger<PasteClusterHandler> _logger = null;

        /// <summary>
        /// 当前是否是主节点
        /// </summary>
        public bool CurrentIsMaster
        {
            get
            {
                if (_current_master != null && _current_node != null)
                {
                    return _current_master.host == _current_node.host;
                }
                return false;
            }
        }

        /// <summary>
        /// 是否是单例模式
        /// 当前节点为null
        /// 或者没有节点列表
        /// </summary>
        public bool IsSingle
        {
            get
            {
                if (_current_master == null || _current_node == null)
                {
                    return true;
                }
                if (node_list == null || node_list.Count <= 1)
                {
                    return true;
                }
                return false;
            }
        }

        /// <summary>
        /// 当前节点的名称 如果为空表示没有或者本身配置就是空
        /// </summary>
        public string CurrentName
        {
            get
            {
                if (_current_node != null)
                {
                    return _current_node.name;
                }
                return "";
            }
        }

        /// <summary>
        /// 获取或设置当前集群的密钥 如果要修改这个需要在所有的调用之前配置
        /// </summary>
        public string SloveToken
        {
            get
            {
                return _config.SloveToken;
            }
            set
            {
                _config.SloveToken = value;
            }
        }

        /// <summary>
        /// 当前节点的名称 如果为空表示没有或者本身配置就是空
        /// </summary>
        public string CurrentHost
        {
            get
            {
                if (_current_node != null)
                {
                    return _current_node.host;
                }
                return "";
            }
        }

        /// <summary>
        /// 当前节点
        /// </summary>
        public PasteNodeModel CurrentNode
        {
            get
            {
                return _current_node;
            }
        }

        /// <summary>
        /// 当前节点的名称 如果为空表示没有或者本身配置就是空
        /// </summary>
        public int CurrentId
        {
            get
            {
                if (_current_node != null)
                {
                    return _current_node.id;
                }
                return 0;
            }
        }

        /// <summary>
        /// 当前配置信息
        /// </summary>
        private PasteSloveConfig _config;

        /// <summary>
        /// 
        /// </summary>
        private List<PasteNodeModel> node_list = null;

        /// <summary>
        /// 是否在选举中
        /// </summary>
        private bool voting = false;

        /// <summary>
        /// 
        /// </summary>
        private System.Timers.Timer _timer;

        /// <summary>
        /// 当前节点的代码，初始值为空，可以被赋值，被赋值后不能再次被赋值
        /// </summary>
        private string node_code = String.Empty;

        /// <summary>
        /// 暂存发往节点的消息，这个是指消息，业务上的消息
        /// </summary>
        private List<PasteEventModel> ziplist = null;

        /// <summary>
        /// 
        /// </summary>
        private System.Threading.SemaphoreSlim _semaphoreSlim;

        /// <summary>
        /// 
        /// </summary>
        private long msg_count = 0;

        private static object lock_nodes;

        /// <summary>
        /// 
        /// </summary>
        public PasteClusterHandler(ILogger<PasteClusterHandler> logger, IOptions<PasteSloveConfig> config, IHttpClientFactory httpClientFactory)
        {
            _logger = logger;
            _config = config.Value;
            _httpClientFactory = httpClientFactory;
            _semaphoreSlim = new SemaphoreSlim(1);
            ziplist = new List<PasteEventModel>();
            _channel_slove = Channel.CreateBounded<PasteEventModel>(_config.SloveChannelMsgCapacity);
            ChannelCluster = Channel.CreateBounded<PasteSloveMessage>(_config.MasterChannelMsgCapacity);

            lock_nodes = new object();

            _timer = new System.Timers.Timer(1000);
            _timer.Elapsed += _timer_Elapsed;
            _timer.AutoReset = true;
            _timer.Start();
            ActionSloveEvent();
        }

        /// <summary>
        /// 当前计数的次数
        /// </summary>
        private int _tick_index = 0;

        /// <summary>
        /// 给当前节点赋值code 
        /// </summary>
        /// <param name="code"></param>
        /// <returns>是否赋值成功</returns>
        public bool SetNodeCode(string code)
        {
            if (String.IsNullOrEmpty(node_code))
            {
                node_code = code;
            }
            else
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 本地用于读取节点列表
        /// </summary>
        /// <returns></returns>
        public PasteNodeModel[] Nodes()
        {
            if (node_list != null)
            {
                return node_list.ToArray();
            }
            return null;
        }

        /// <summary>
        /// 启动集群
        /// 读取ClusterHost作为集群列表
        /// 读取CurrentHost作为当前节点得Host
        /// 如果有NodeList和NodeCode(CurrentCode)触发查找自己
        /// 否则触发查找Master
        /// </summary>
        public async void StartCluster()
        {
            if (!string.IsNullOrEmpty(_config.CurrentHost))
            {
                Register(_config.CurrentHost, 0, 0);
            }
            if (!String.IsNullOrEmpty(_config.ClusterHost))
            {
                var _list = new List<PasteNodeModel>();
                var strs = _config.ClusterHost.Split(";");
                foreach (var str in strs)
                {
                    if (!string.IsNullOrEmpty(str))
                    {
                        var its = str.Split(',');
                        var _one = new PasteNodeModel { };
                        _one.host = its[0];
                        if (its.Length > 1)
                        {
                            int.TryParse(its[1], out var _id);
                            _one.id = _id;
                        }
                        if (its.Length > 2)
                        {
                            int.TryParse(its[2], out var _group);
                            _one.group = _group;
                        }
                        if (!_list.Contains(_one))
                        {
                            _list.Add(_one);
                        }
                    }
                }
                if (_list.Count > 0)
                {
                    foreach (var _one in _list)
                    {
                        AddNodeToList(_one);
                    }
                }
            }

            if (!String.IsNullOrEmpty(_config.CurrentCode))
            {
                SetNodeCode(_config.CurrentCode);
            }
            if (!String.IsNullOrEmpty(node_code))
            {
                if (node_list != null && node_list.Count > 0)
                {
                    await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.findnode });
                }
            }
            else
            {
                //Console.WriteLine("begin to join cluster:" + node_list.Select(x => x.host).ToString());
                await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.scanmaster, message = "", time = DateTime.Now.ToUnixTimeMilliseconds() });
            }
        }

        /// <summary>
        /// 需要确保先调用SetNodeCode 表示给自己打一个标记
        /// 然后会启动一个任务去遍历集合，查找这个NodeCode,找到后就知道自己的HOST信息了
        /// </summary>
        public async void FindMe()
        {
            if (!String.IsNullOrEmpty(node_code))
            {
                if (node_list != null && node_list.Count > 0)
                {
                    await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.findnode });
                }
            }
        }

        /// <summary>
        /// 开始查找自己 需要有节点集合(通过AddNodeToList赋值) 需要有当前节点得node_code(通过SetNodeCode赋值)
        /// </summary>
        /// <returns></returns>
        public async Task<bool> StartFindMe()
        {
            if (!String.IsNullOrEmpty(node_code))
            {
                if (node_list != null && node_list.Count > 0)
                {
                    await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.findnode });
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 如果消息来自Master则更新我和Master的最后交互时间
        /// 这个功能用于减少不必要的心跳资源浪费
        /// </summary>
        /// <param name="host"></param>
        public void TargetMasterLast(string host)
        {
            if (_current_master != null)
            {
                if (_current_master.host == host)
                {
                    _current_master.last_time = DateTime.Now.ToUnixTimeSeconds();
                    //Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} Node:{CurrentHost} Update Master Last Time!");
                }
            }
        }

        /// <summary>
        /// 确认对方的Master和我的是否一致！
        /// 如果不一致，则我进去查找Master阶段
        /// </summary>
        /// <param name="host"></param>
        public void ConfirmMaster(string host)
        {
            if (_current_master != null)
            {
                if (_current_master.host != host)
                {
                    _current_master = null;
                    _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.scanmaster });
                }
            }
        }

        /// <summary>
        /// 拥有集群的地址列表，去找到自己
        /// 这个是给内部调用的，请勿调用
        /// </summary>
        /// <param name="input"></param>
        public async Task<PasteApiResponse> Find(PasteNodeModel input)
        {
            if (!String.IsNullOrEmpty(input.node_code))
            {
                if (node_code == input.node_code)
                {
                    //找到自己了
                    _current_node = new PasteNodeModel
                    {
                        node_code = node_code,
                        group = input.group,
                        host = input.host,
                        id = input.id,
                    };
                    AddNodeToList(_current_node);
                    await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.scanmaster, message = "", time = DateTime.Now.ToUnixTimeMilliseconds() });
                    await ChannelCluster.Writer.WriteAsync(new PasteSloveMessage { msg_type = 2, body = Newtonsoft.Json.JsonConvert.SerializeObject(_current_node), from = _current_node });
                }
            }
            return new PasteApiResponse { success = true, master = _current_master, node = _current_node };
        }

        private bool time_elapsed_running = false;

        /// <summary>
        /// 定时检查
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (time_elapsed_running)
            {
                return;
            }
            try
            {
                time_elapsed_running = true;
                if (_current_node != null)
                {
                    _tick_index++;
                    //健康检查 被检查等！
                    if (_tick_index % _config.TickSloveHealth == 0)
                    {
                        var _ago = DateTime.Now.ToUnixTimeSeconds() - _config.TickScanSloveHealth;
                        if (CurrentIsMaster)
                        {
                            //健康检查 检查节点多久没通讯了
                            if (node_list != null && node_list.Count > 0)
                            {
                                var _post = new PasteMasterResponse { };
                                _post.master = _current_node;
                                _post.nodes = node_list?.ToArray();
                                var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(_post);
                                for (var k = 0; k < node_list.Count; k++)
                                {
                                    var _node = node_list[k];
                                    if (_node.host != _current_node.host)
                                    {
                                        if (_node.last_time < _ago)
                                        {
                                            var _api = await api_get(_node, _config.ApiHealth);
                                            if (_api.success)
                                            {
                                                if (_api.node_count != node_list.Count || _api.master?.host != _current_master?.host)
                                                {
                                                    //告知对方，你的集群数据有误！
                                                    await api_post(_node, _postBody, _config.ApiMaster);
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        _node.last_time = DateTime.Now.ToUnixTimeSeconds();//自己直接就是最新的
                                    }
                                }

                                //错误次数超过多少次的 执行移除操作！
                                var removes = node_list.Where(x => x.error_time > _config.RemoveByTime).ToList();
                                if (removes != null && removes.Count > 0)
                                {
                                    foreach (var _node in removes)
                                    {
                                        await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.removenode, message = Newtonsoft.Json.JsonConvert.SerializeObject(_node) });
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (_current_master != null)
                            {
                                if (_current_master.last_time < _ago)
                                {
                                    //Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} node:{_current_node?.host} master:{_current_master?.host} timeout!");
                                    var _nodeBody = Newtonsoft.Json.JsonConvert.SerializeObject(_current_node);
                                    var _api = await api_post(_current_master, _nodeBody, _config.ApiLink);
                                    if (_api.success)
                                    {
                                        //我记录的master和master记录的master不一致
                                        if (_api.node_count != node_list.Count || _api.master?.host != _current_master?.host)
                                        {
                                            _current_master = null;
                                            await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.scanmaster });
                                        }
                                    }
                                    else
                                    {
                                        _current_master = null;
                                        await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.scanmaster });
                                    }
                                }
                            }
                            else
                            {
                                await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.scanmaster });
                            }
                        }
                    }
                }
                if (_tick_index > 3600)
                {
                    _tick_index = 0;
                }
            }
            catch (Exception exlelapsed)
            {
                _logger.LogError("line.396 " + exlelapsed.Message);
                _logger.LogError(exlelapsed.StackTrace);
            }
            finally
            {
                time_elapsed_running = false;
            }
        }

        /// <summary>
        /// 业务端调用 表示把消息打入到集群 发给所有节点或者某些节点
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="msg_type">大于10 基于你的业务需求自定义</param>
        /// <param name="node_id"></param>
        /// <param name="group"></param>
        /// <param name="name">节点名称</param>
        public void PushMsgToNode(string msg, int msg_type = 0, int node_id = 0, int group = 0, string name = "")
        {
            var _msg = new PasteSloveMessage
            {
                body = msg,
                msg_type = msg_type,
                from = _current_node
            };
            var _msgbody = Newtonsoft.Json.JsonConvert.SerializeObject(_msg);
            if (!voting)
            {
                //如果当前在选举中，则暂存！
                _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.msg_to_node, message = _msgbody, msg_type = msg_type, node_id = node_id, group = group, name = name });
            }
            else
            {
                ziplist.Add(new PasteEventModel { action = PasteSloveEvent.msg_to_node, message = _msgbody, msg_type = msg_type, node_id = node_id, group = group, name = name });
            }
        }

        /// <summary>
        /// 把消息发送给所有节点，包括自己
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="msg_type">大于10 基于你的业务需求自定义</param>
        public void PushMsgToAll(string msg, int msg_type = 0)
        {
            var _msg = new PasteSloveMessage
            {
                body = msg,
                msg_type = msg_type,
                from = _current_node
            };
            var _msgbody = Newtonsoft.Json.JsonConvert.SerializeObject(_msg);
            if (!voting)
            {
                //如果当前在选举中，则暂存！
                _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.msg_to_all_node, message = _msgbody, msg_type = msg_type });
            }
            else
            {
                ziplist.Add(new PasteEventModel { action = PasteSloveEvent.msg_to_all_node, message = _msgbody, msg_type = msg_type });
            }
        }

        /// <summary>
        /// 发送消息给master所在的节点的业务处理，如果当前为master则变更channel，切换到给业务处理
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="msg_type">大于10 基于你的业务需求自定义</param>
        public void PushMsgToMaster(string msg, int msg_type = 0)
        {
            var _msg = new PasteSloveMessage
            {
                body = msg,
                from = _current_node,
                msg_type = msg_type
            };
            var _msgbody = Newtonsoft.Json.JsonConvert.SerializeObject(_msg);
            if (CurrentIsMaster || _current_master == null)
            {
                //切换队列
                ChannelCluster.Writer.WriteAsync(new PasteSloveMessage { body = _msgbody, msg_type = msg_type });
            }
            else
            {
                if (!voting)
                {
                    _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.msg_to_master, message = _msgbody, msg_type = msg_type });
                }
                else
                {
                    ziplist.Add(new PasteEventModel { action = PasteSloveEvent.msg_to_master, message = _msgbody, msg_type = msg_type });
                }
            }
        }

        /// <summary>
        /// 直接推送消息，主要作用在于立马反馈
        /// 如果没有对象，则会发送给master
        /// 可以从from中判断是不是回环了
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="msg_type"></param>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <param name="group"></param>
        /// <param name="host"></param>
        /// <returns></returns>
        public async Task<bool> PushDirectionMsg(string msg, int msg_type = 0, int id = 0, string name = "", int group = 0, string host = "")
        {
            var _message = new PasteSloveMessage
            {
                body = msg,
                msg_type = msg_type,
                from = _current_node
            };
            return await PushDirectionMsg(_message, id, name, group, host);
        }

        /// <summary>
        /// 直接发送消息给某一个节点
        /// 如果没有命中则发送给Master
        /// 也就是说，可能发送给当前！注意不要回环了！！！
        /// </summary>
        /// <param name="message"></param>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <param name="group"></param>
        /// <param name="host">示例http://192.168.1.5</param>
        /// <returns>是否发送成功，发送给某一个节点了?</returns>
        public async Task<bool> PushDirectionMsg(PasteSloveMessage message, int id = 0, string name = "", int group = 0, string host = "")
        {
            message.from = _current_node;
            var _send = false;
            if (id != 0)
            {
                if (CurrentId == id)
                {
                    message.to = _current_node;
                    var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(message);
                    var _message = Newtonsoft.Json.JsonConvert.DeserializeObject<PasteSloveMessage>(_postBody);
                    await ChannelCluster.Writer.WriteAsync(_message);
                    return true;
                }
                else
                {
                    var find = node_list.Where(x => x.id == id).FirstOrDefault();
                    if (find != null && find != default)
                    {
                        message.to = find;
                        var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(message);
                        var _api = await api_post(find, _postBody, _config.ApiMsg);
                        return _api.success;
                    }
                }
            }

            if (!string.IsNullOrEmpty(host) && node_list != null)
            {
                var find = node_list.Where(x => x.host == host).FirstOrDefault();
                if (find != null && find != default)
                {
                    message.to = find;
                    var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(message);
                    var _api = await api_post(find, _postBody, _config.ApiMsg);
                    return _api.success;
                }
            }

            if (!string.IsNullOrEmpty(name) && node_list != null)
            {
                var find = node_list.Where(x => x.name == name).FirstOrDefault();
                if (find != null && find != default)
                {
                    message.to = find;
                    var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(message);
                    var _api = await api_post(find, _postBody, _config.ApiMsg);
                    return _api.success;
                }
            }
            if (group != 0 && node_list != null)
            {
                var find = node_list.Where(x => x.group == group).FirstOrDefault();
                if (find != null && find != default)
                {
                    message.to = find;
                    var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(message);
                    var _api = await api_post(find, _postBody, _config.ApiMsg);
                    return _api.success;
                }
            }

            if (!_send)
            {
                if (CurrentIsMaster || IsSingle)
                {
                    message.to = _current_node;
                    await ChannelCluster.Writer.WriteAsync(message);
                    return true;
                }
                else
                {
                    if (_current_master != null)
                    {
                        message.to = _current_master;
                        var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(message);
                        var _api = await api_post(_current_master, _postBody, _config.ApiMsg);
                        return _api.success;
                    }
                }
            }
            return _send;
        }

        /// <summary>
        /// 如果当前不是master则不执行，直接抛弃，如果当前是master则执行
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="msg_type">大于10</param>
        /// <returns></returns>
        public async Task<bool> PushMsgToOnlyMaster(string msg, int msg_type = 0)
        {
            var _msg = new PasteSloveMessage
            {
                body = msg,
                msg_type = msg_type,
                from = _current_node
            };
            var _msgbody = Newtonsoft.Json.JsonConvert.SerializeObject(_msg);
            if (CurrentIsMaster || _current_master == null)
            {
                await ChannelCluster.Writer.WriteAsync(new PasteSloveMessage { body = _msgbody, msg_type = msg_type });
                return true;
            }
            return false;
        }

        /// <summary>
        /// 处理节点中队列的消息
        /// </summary>
        private async void ActionSloveEvent()
        {
            try
            {
                var _read = await _channel_slove.Reader.ReadAsync();
                if (_read != null && _read != default)
                {
                    _logger.LogInformation(Newtonsoft.Json.JsonConvert.SerializeObject(_read));
                    switch (_read.action)
                    {
                        case PasteSloveEvent.votemaster:
                            {
                                //告知别人，我是master
                                if (_current_node == null)
                                {
                                    return;
                                }
                                if (_current_master != null)
                                {
                                    return;
                                }
                                if (voting)
                                {
                                    return;
                                }
                                voting = true;
                                //Console.WriteLine("--- votemaster ---");
                                _current_node.vote_time = DateTime.Now.ToUnixTimeMilliseconds();
                                if (node_list != null && node_list.Count > 0)
                                {
                                    var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(_current_node);
                                    //必须大于1，有2个及以上节点，才有master的说法
                                    for (var k = 0; k < node_list.Count; k++)
                                    {
                                        var _node = node_list[k];
                                        if (_node.host != _current_node.host && voting)
                                        {
                                            var _api = await api_post(_node, _postBody, _config.ApiVote);
                                            if (_api.success)
                                            {
                                                if (_api.master != null)
                                                {
                                                    if (_api.master.host != _current_node.host)
                                                    {
                                                        voting = false;
                                                        _current_master = _api.master;
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    //选举完成了，我是不是master?
                                    if (_current_master == null)
                                    {
                                        voting = false;
                                        _current_master = _current_node;
                                        await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.suremaster });
                                    }
                                }
                            }
                            break;
                        case PasteSloveEvent.scanmaster:
                            {
                                if (_current_node == null)
                                {
                                    return;
                                }
                                if (_current_master != null)
                                {
                                    return;
                                }
                                if (voting)
                                {
                                    return;
                                }
                                //Console.WriteLine("--- scanmaster ---");
                                _current_node.vote_time = DateTime.Now.ToUnixTimeMilliseconds();
                                if (node_list != null && node_list.Count > 0)
                                {
                                    voting = true;
                                    var _masters = new List<PasteNodeModel>();
                                    //必须大于1，有2个及以上节点，才有master的说法
                                    for (var k = 0; k < node_list.Count; k++)
                                    {
                                        var _node = node_list[k];
                                        if (_node.host != _current_node.host)
                                        {
                                            var _api = await api_get(_node, _config.ApiAsk);
                                            if (_api.success && _api.master != null)
                                            {
                                                var _find = _masters.Where(x => x.host == _api.master.host).FirstOrDefault();
                                                if (_find == null || _find == default)
                                                {
                                                    _masters.Add(_api.master);
                                                }
                                            }
                                        }
                                    }
                                    if (_masters != null && _masters.Count > 0)
                                    {
                                        var _currents = _masters.OrderBy(x => x.vote_time).ToList();
                                        foreach (var _current in _currents)
                                        {
                                            var _api = await api_get(_current, _config.ApiAsk);
                                            if (_api.success && _api.master != null)
                                            {
                                                voting = false;
                                                _current_master = _api.master;
                                                if (_current_node.host == _current_master.host)
                                                {
                                                    await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.suremaster });
                                                }
                                            }
                                        }
                                    }
                                    if (_current_master != null)
                                    {
                                        if (_current_node?.host != _current_master?.host)
                                        {
                                            //告知 master 我要加入集群
                                            var _join = await api_post(_current_master, Newtonsoft.Json.JsonConvert.SerializeObject(_current_node), _config.ApiJoinSlove);
                                            if (!_join.success)
                                            {
                                                //这里失败了，咋办??? 未完待续
                                                voting = false;
                                                _current_master = null;
                                                //扫描失败，等待下一次
                                            }
                                        }
                                    }
                                    else
                                    {
                                        //饶了一圈，全部不能访问
                                        voting = false;
                                        _current_master = _current_node;
                                        await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.suremaster });
                                    }
                                }
                                else
                                {
                                    //节点信息不完整 还是只有这么一个节点？ 未完待续
                                    voting = false;
                                    _current_master = _current_node;
                                    await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.suremaster });
                                }
                            }
                            break;
                        case PasteSloveEvent.suremaster:
                            {
                                if (_current_node == null)
                                {
                                    return;
                                }
                                if (voting)
                                {
                                    voting = false;
                                }
                                AddNodeToList(_current_node);//把自己加进去，有可能丢了自己！
                                if (node_list != null && node_list.Count > 0)
                                {
                                    var _post = new PasteMasterResponse { };
                                    _post.master = _current_node;
                                    _post.nodes = node_list?.ToArray();
                                    var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(_post);
                                    if (!string.IsNullOrEmpty(_read.to_host))
                                    {
                                        var _node = node_list.Where(x => x.host == _read.to_host).FirstOrDefault();
                                        if (_node != null && _node != default)
                                        {
                                            var _api = await api_post(_node, _postBody, _config.ApiMaster);
                                        }
                                    }
                                    else
                                    {
                                        for (var k = 0; k < node_list.Count; k++)
                                        {
                                            var _node = node_list[k];
                                            if (_node.host != _current_node.host)
                                            {
                                                var _api = await api_post(_node, _postBody, _config.ApiMaster);
                                            }
                                        }
                                    }
                                    await ChannelCluster.Writer.WriteAsync(new PasteSloveMessage { msg_type = 1, body = _postBody, from = _current_node, time = DateTime.Now.ToUnixTimeSeconds() });
                                }
                            }
                            break;
                        case PasteSloveEvent.msg_to_master:
                            {
                                var _message = Newtonsoft.Json.JsonConvert.DeserializeObject<PasteSloveMessage>(_read.message);
                                if (CurrentIsMaster)
                                {
                                    _message.from = _current_node;
                                    _message.to = _current_node;
                                    await ChannelCluster.Writer.WriteAsync(_message);
                                }
                                else
                                {
                                    //通过 api 发送给 master
                                    if (_current_master != null)
                                    {
                                        _message.from = _current_node;
                                        _message.to = _current_master;
                                        var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(_message);
                                        //如果发送失败，暂停业务，进行vote阶段
                                        var _join = await api_post(_current_master, _postBody, _config.ApiMsg);
                                        if (!_join.success)
                                        {
                                            if (_read.try_time > 0)
                                            {
                                                _read.try_time = _read.try_time - 1;
                                                //这里失败了，咋办??? 未完待续
                                                await _channel_slove.Writer.WriteAsync(_read);
                                            }
                                        }
                                    }
                                }
                            }
                            break;
                        case PasteSloveEvent.msg_to_node:
                            {
                                if (node_list == null || node_list.Count == 0)
                                {
                                    return;
                                }
                                var _message = Newtonsoft.Json.JsonConvert.DeserializeObject<PasteSloveMessage>(_read.message);
                                if (_read.node_id != 0)
                                {
                                    var nodes = node_list.Where(x => x.id == _read.node_id).ToList();
                                    if (nodes != null && nodes.Count > 0)
                                    {
                                        foreach (var _node in nodes)
                                        {
                                            _message.to = _node;
                                            var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(_message);
                                            var _api = await api_post(_node, _postBody, _config.ApiMsg);
                                        }
                                    }
                                }
                                if (_read.group != 0)
                                {
                                    var nodes = node_list.Where(x => x.group == _read.group).ToList();
                                    if (nodes != null && nodes.Count > 0)
                                    {
                                        foreach (var _node in nodes)
                                        {
                                            _message.to = _node;
                                            var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(_message);
                                            var _api = await api_post(_node, _postBody, _config.ApiMsg);
                                        }
                                    }
                                }
                                if (_read.group == 0 && _read.node_id == 0)
                                {
                                    for (var k = 0; k < node_list.Count; k++)
                                    {
                                        var _node = node_list[k];
                                        _message.to = _node;
                                        var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(_message);
                                        var _api = await api_post(_node, _postBody, _config.ApiMsg);
                                    }
                                }
                            }
                            break;
                        case PasteSloveEvent.msg_to_all_node:
                            {
                                if (node_list == null || node_list.Count == 0)
                                {
                                    return;
                                }
                                var _message = Newtonsoft.Json.JsonConvert.DeserializeObject<PasteSloveMessage>(_read.message);
                                for (var k = 0; k < node_list.Count; k++)
                                {
                                    var _node = node_list[k];
                                    _message.to = _node;
                                    var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(_message);
                                    var _api = await api_post(_node, _postBody, _config.ApiMsg);
                                }
                            }
                            break;
                        case PasteSloveEvent.removenode:
                            {
                                if (CurrentIsMaster)
                                {
                                    var _node = Newtonsoft.Json.JsonConvert.DeserializeObject<PasteNodeModel>(_read.message);
                                    RemoveCurrentNode(_node);
                                    //下发群发消息
                                    await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.suremaster });
                                    var _messge = new PasteSloveMessage
                                    {
                                        body = _read.message,
                                        from = _current_node,
                                        msg_type = 4,
                                    };
                                    await ChannelCluster.Writer.WriteAsync(_messge);
                                }
                            }
                            break;
                        case PasteSloveEvent.unziplist:
                            {
                                if (ziplist != null && ziplist.Count > 0)
                                {
                                    var _count = ziplist.Count;
                                    //Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}将从队列ZIPLIST中发送{ziplist.Count}条消息");
                                    for (var k = 0; k < _count; k++)
                                    {
                                        if (!voting)
                                        {
                                            if (ziplist.Count > 0)
                                            {
                                                var _first = ziplist[0];
                                                await _channel_slove.Writer.WriteAsync(_first);
                                                ziplist.RemoveAt(0);
                                            }
                                        }
                                    }
                                }
                                break;
                            }
                        case PasteSloveEvent.findnode:
                            {
                                var _find = false;
                                if (!string.IsNullOrEmpty(node_code))
                                {
                                    if (node_list != null && node_list.Count > 0)
                                    {
                                        for (var k = 0; k < node_list.Count; k++)
                                        {
                                            var _node = node_list[k];
                                            if (String.IsNullOrEmpty(_node.node_code))
                                            {
                                                var _build = new PasteNodeModel
                                                {
                                                    group = _node.group,
                                                    id = _node.id,
                                                    host = _node.host,
                                                    node_code = node_code
                                                };
                                                var _api = await api_post(_build, Newtonsoft.Json.JsonConvert.SerializeObject(_build), _config.ApiFind);
                                                if (_api.success)
                                                {
                                                    if (_api.node != null)
                                                    {
                                                        if (_api.node.node_code == node_code)
                                                        {
                                                            _find = true;
                                                            break;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                if (_find)
                                {
                                    await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.scanmaster, message = "", time = DateTime.Now.ToUnixTimeMilliseconds() });
                                }
                            }
                            break;
                        case PasteSloveEvent.broadmaster:
                            {
                                if (!CurrentIsMaster)
                                {
                                    if (_current_node != null && _current_master != null)
                                    {
                                        await api_get(_current_master, _config.ApiBroad);
                                    }
                                }
                            }
                            break;
                    }
                }
            }
            catch (Exception exl)
            {
                _logger.LogError("line.1066 " + exl.Message);
                _logger.LogError(exl.StackTrace);
                await Task.Delay(1000);
            }
            finally
            {
                ActionSloveEvent();
            }
        }

        /// <summary>
        /// 知道当前节点信息后，注册到节点或者更新当前节点信息
        /// </summary>
        /// <param name="host"></param>
        /// <param name="id"></param>
        /// <param name="group"></param>
        /// <param name="name"></param>
        public async void Register(string host, int id, int group = 0, string name = "")
        {
            var _current = new PasteNodeModel
            {
                group = group,
                host = host,
                id = id,
                name = name,
                last_time = DateTime.Now.ToUnixTimeSeconds()
            };
            _current_node = _current;
            AddNodeToList(_current);
            //准备问询
            await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.scanmaster, message = "", time = DateTime.Now.ToUnixTimeMilliseconds() });
            await ChannelCluster.Writer.WriteAsync(new PasteSloveMessage { msg_type = 2, body = Newtonsoft.Json.JsonConvert.SerializeObject(_current_node), from = _current_node });
        }

        /// <summary>
        /// 有新的节点加入 可以是业务上读取节点列表，然后遍历调用这个
        /// </summary>
        /// <param name="input"></param>
        public async void Join(PasteNodeModel input)
        {
            AddNodeToList(input);
            //群发
            if (CurrentIsMaster)
            {
                await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.suremaster, to_host = input.host });

                //告知系统有新的节点
                var _messge = new PasteSloveMessage
                {
                    body = Newtonsoft.Json.JsonConvert.SerializeObject(input),
                    from = _current_node,
                    msg_type = 3,
                };
                await ChannelCluster.Writer.WriteAsync(_messge);
            }
        }

        /// <summary>
        /// 添加节点
        /// </summary>
        /// <param name="input"></param>
        public void AddNodeToList(PasteNodeModel input)
        {
            try
            {
                lock (lock_nodes)
                {
                    if (node_list == null)
                    {
                        node_list = new List<PasteNodeModel> { input };
                    }
                    else
                    {
                        var find = node_list.Where(x => x.host == input.host).FirstOrDefault();
                        if (find != null && find != default)
                        {
                            find.id = input.id;
                            find.group = input.group;
                        }
                        else
                        {
                            node_list.Add(input);
                        }
                    }
                    _logger.LogInformation($"Node.Host:{input?.host} Join to List!");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("line.1152 " + ex.Message);
                _logger.LogError(ex.StackTrace);
            }
            finally
            {
                //_semaphoreSlim.Release();
            }
        }

        /// <summary>
        /// 扫描master 这个发生在加入新的节点信息后 或者启动后
        /// </summary>
        public async void ScanMaster()
        {
            await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.scanmaster });
        }

        /// <summary>
        /// 健康检查，返回当前信息
        /// </summary>
        /// <returns></returns>
        public PasteApiResponse Health()
        {
            return new PasteApiResponse { success = true, master = _current_master, node = _current_node, node_count = node_list != null ? node_list.Count : 0 };
        }

        /// <summary>
        /// 健康检查，返回当前信息
        /// </summary>
        /// <returns></returns>
        public async Task<PasteApiResponse> Link(PasteNodeModel node)
        {
            if (CurrentIsMaster)
            {
                if (node_list != null)
                {
                    if (!node_list.Where(x => x.host == node.host).Any())
                    {
                        AddNodeToList(node);
                        await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.suremaster, to_host = node.host });
                    }
                }
            }
            return new PasteApiResponse { success = true, master = _current_master, node = _current_node, node_count = node_list != null ? node_list.Count : 0 };
        }

        /// <summary>
        /// 被问询 当前有没有master
        /// </summary>
        public async Task<PasteApiResponse> Ask()
        {
            if (_current_node != null)
            {
                if (_current_master != null)
                {
                    if (_current_master.host == _current_node.host)
                    {
                        return State();
                    }
                    var _ago = DateTime.Now.ToUnixTimeSeconds() - _config.TickSloveHealth;
                    if (_current_master.last_time >= _ago)
                    {
                        //通知 master 群发
                        await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.broadmaster });
                        return State();
                    }
                    var _api = await api_get(_current_master, _config.ApiHealth);
                    if (_api.success)
                    {
                        //通知 master 群发
                        await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.broadmaster });
                        return State();
                    }
                    else
                    {
                        _current_master = null;
                    }
                }
                if (_current_master == null)
                {
                    _current_node.vote_time = DateTime.Now.ToUnixTimeMilliseconds();
                    await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.votemaster, message = "", time = DateTime.Now.ToUnixTimeMilliseconds() });
                }
            }
            return State();
        }

        /// <summary>
        /// 集群间的消息
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public async Task<PasteApiResponse> Msg(PasteSloveMessage msg)
        {
            await ChannelCluster.Writer.WriteAsync(msg);
            msg_count++;
            if (msg.msg_type == 2)
            {

            }
            return new PasteApiResponse { success = true, master = _current_master, node = _current_node };
        }

        /// <summary>
        /// 对外即将对外广播，我是master
        /// </summary>
        /// <returns></returns>
        public async Task<PasteApiResponse> Broad()
        {
            if (CurrentIsMaster)
            {
                await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.suremaster });
            }
            return State();
        }

        /// <summary>
        /// 有master分发消息，说他是master
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PasteApiResponse> Vote(PasteNodeModel input)
        {
            if (_current_node != null)
            {
                //排除当前节点问当前节点
                if (_current_node.host != input.host)
                {
                    if (_current_master == null)
                    {
                        voting = false;
                        _current_master = input;
                    }
                    else
                    {
                        if (_current_master.host != input.host)
                        {
                            if (_current_master.vote_time < input.vote_time)
                            {
                                var _api = await api_get(_current_master, _config.ApiHealth);
                                if (_api.success)
                                {
                                    return new PasteApiResponse { success = true, master = _current_master, node = _current_node };
                                }
                                else
                                {
                                    voting = false;
                                    _current_master = input;
                                }
                            }
                        }
                        return new PasteApiResponse { success = true, master = _current_master, node = _current_node };
                    }
                }
            }
            //返回 哪个是master
            return new PasteApiResponse { success = true, master = input, node = _current_node };
        }

        /// <summary>
        /// master选举完成，master广播说他是master
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PasteApiResponse> Master(PasteMasterResponse input)
        {
            var _old_is_master = CurrentIsMaster;
            voting = false;
            
            _current_master = input.master;

            if (input.nodes != null && input.nodes.Length > 0)
            {
                foreach (var _node in input.nodes)
                {
                    AddNodeToList(_node);
                }
                var nodes = input.nodes.Select(x => x.host).ToArray();
                if (node_list != null && node_list.Count > 0)
                {
                    var dels = node_list.Where(x => !nodes.Contains(x.host)).ToArray();
                    if (dels.Length > 0)
                    {
                        foreach (var del in dels)
                        {
                            RemoveCurrentNode(del);
                        }
                    }
                }
                if (_current_node != null)
                {
                    if (node_list != null)
                    {
                        if (!node_list.Where(x => x.host == _current_node.host).Any())
                        {
                            _current_master = null;
                            await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.scanmaster, message = "", time = DateTime.Now.ToUnixTimeMilliseconds() });
                            return State();
                        }
                    }
                }
            }
            voting = false;
            var _new_is_master = CurrentIsMaster;
            if (_old_is_master && !_new_is_master)
            {
                await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.unziplist });
                //await ChannelCluster.Writer.WriteAsync(new PasteSloveMessage { msg_type = 2, body = Newtonsoft.Json.JsonConvert.SerializeObject(input), from = _current_node });
                await ChannelCluster.Writer.WriteAsync(new PasteSloveMessage { msg_type = 5, body = Newtonsoft.Json.JsonConvert.SerializeObject(input), from = _current_node });
            }
            return State();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PasteApiResponse> Leave(PasteNodeModel input)
        {
            if (_current_node != null)
            {
                if (_current_node.host != input.host)
                {
                    //谁离线了
                    //如果自己是master 则应该是节点离线 通知其他节点，节点列表变更
                    //如果自己是node 离线的是master 则自己进去选择
                    if (CurrentIsMaster)
                    {
                        if (node_list != null && node_list.Count > 0)
                        {
                            RemoveCurrentNode(input);
                            if (node_list.Count > 0)
                            {
                                var _post = new PasteMasterResponse { };
                                _post.master = _current_node;
                                _post.nodes = node_list?.ToArray();
                                var _postBody = Newtonsoft.Json.JsonConvert.SerializeObject(_post);
                                for (var k = 0; k < node_list.Count; k++)
                                {
                                    var _node = node_list[k];
                                    if (_node.host != _current_node.host && _node.host != input.host)
                                    {
                                        var _api = await api_post(_node, _postBody, _config.ApiMaster);
                                    }
                                }
                            }
                        }
                        //告知系统有新的节点
                        var _messge = new PasteSloveMessage
                        {
                            body = Newtonsoft.Json.JsonConvert.SerializeObject(input),
                            from = _current_node,
                            msg_type = 4,
                        };
                        await ChannelCluster.Writer.WriteAsync(_messge);
                    }
                    else
                    {
                        if (_current_master != null && input.host == _current_master.host)
                        {
                            _current_master = null;
                            await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.scanmaster });
                        }
                    }
                }
            }
            return new PasteApiResponse { success = true, master = _current_master, node = _current_node };
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PasteApiResponse> Remove(PasteNodeModel input)
        {
            if (_current_node != null)
            {
                if (_current_node.host == input.host)
                {
                    _current_master = null;
                    await _channel_slove.Writer.WriteAsync(new PasteEventModel { action = PasteSloveEvent.scanmaster });
                }
                RemoveCurrentNode(input);
            }
            return new PasteApiResponse { success = true, master = _current_master, node = _current_node };
        }

        /// <summary>
        /// 移除节点
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private void RemoveCurrentNode(PasteNodeModel input)
        {
            try
            {
                lock (lock_nodes)
                {
                    if (node_list != null)
                    {
                        var find = node_list.Where(x => x.host == input.host).FirstOrDefault();
                        if (find != null && find != default)
                        {
                            node_list.Remove(find);
                        }
                    }
                }
                _logger.LogInformation($"Node.Host:{input?.host} Leave List!");
            }
            catch (Exception exl)
            {
                _logger.LogError("line.1427 " + exl.Message);
                _logger.LogError(exl.StackTrace);
            }
            finally
            {
                //_semaphoreSlim.Release();
            }
        }

        /// <summary>
        /// 打印当前状态
        /// </summary>
        /// <returns></returns>
        public string Status()
        {
            return $"Total:{node_list?.Count} Master:{_current_master?.host} Error:{_current_master?.error_time} Current:{_current_node?.host} MsgCount:{msg_count} ZipSize:{ziplist?.Count} \t\n";
        }

        /// <summary>
        /// 打印当前状态
        /// </summary>
        /// <returns></returns>
        public PasteApiResponse State()
        {
            return new PasteApiResponse { success = true, master = _current_master, node = _current_node };
        }

        /// <summary>
        /// 离线 告诉除了自己的第一个节点，我要离线了！
        /// </summary>
        private async Task _leave()
        {
            if (CurrentIsMaster)
            {
                if (node_list != null && node_list.Count > 0)
                {
                    if (_current_node != null)
                    {
                        for (var k = 0; k < node_list.Count; k++)
                        {
                            var _node = node_list[k];
                            if (_node.host != _current_node?.host)
                            {
                                var _api = await api_post(_node, Newtonsoft.Json.JsonConvert.SerializeObject(_current_node), $"{_config.ApiLeave}");
                                if (_api.success)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                if (_current_master != null && _current_node != null)
                {
                    await api_post(_current_master, Newtonsoft.Json.JsonConvert.SerializeObject(_current_node), $"{_config.ApiLeave}");
                }
            }
        }

        #region

        /// <summary>
        /// 
        /// </summary>
        /// <param name="node"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        private async Task<PasteApiResponse> api_get(PasteNodeModel node, string path)
        {
            var _read = await get($"{node.host}{path}", node.host);
            if (_read.code == 200)
            {
                if (node.error_time > 0)
                {
                    node.error_time = 0;
                }
                node.last_time = DateTime.Now.ToUnixTimeSeconds();
                return Newtonsoft.Json.JsonConvert.DeserializeObject<PasteApiResponse>(_read.response);
            }
            else
            {
                node.error_time++;
                return new PasteApiResponse { success = false };
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="node"></param>
        /// <param name="body"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        private async Task<PasteApiResponse> api_post(PasteNodeModel node, string body, string path)
        {
            var _read = await post($"{node.host}{path}", body, node.host);
            if (_read.code == 200)
            {
                if (node.error_time > 0)
                {
                    node.error_time = 0;
                }
                node.last_time = DateTime.Now.ToUnixTimeSeconds();
                return Newtonsoft.Json.JsonConvert.DeserializeObject<PasteApiResponse>(_read.response);
            }
            else
            {
                node.error_time++;
                return new PasteApiResponse { success = false };
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="host"></param>
        /// <returns></returns>
        private async Task<(int code, string response)> get(string url, string host)
        {
            try
            {
                var request = new HttpRequestMessage(HttpMethod.Get, url);
                request.Headers.Add("slovetoken", _config.SloveToken);
                if (_current_node != null)
                {
                    request.Headers.Add("fromnode", _current_node?.host);
                }
                if (_current_master != null)
                {
                    request.Headers.Add("masternode", _current_master?.host);
                }
                request.Headers.Add("ContentType", "application/json;charset=utf-8");
                var client = _httpClientFactory.CreateClient();
                client.Timeout = TimeSpan.FromSeconds(4);
                client.DefaultRequestHeaders.Add("ContentType", "application/json;charset=utf-8");
                var response = await client.SendAsync(request);
                using var stream = new StreamReader(await response.Content.ReadAsStreamAsync(), Encoding.UTF8);
                var backstream = stream.ReadToEnd();
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    _logger.LogInformation(backstream);
                }
                else
                {
                    _logger.LogError("line.1572 " + backstream);
                }
                return ((int)response.StatusCode, backstream);
            }
            catch (Exception exl)
            {
                _logger.LogError("line.1578 " + exl.Message);
                _logger.LogError(exl.StackTrace);
                return (500, exl.Message);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="postdata"></param>
        /// <param name="host"></param>
        /// <returns></returns>
        private async Task<(int code, string response)> post(string url, string postdata, string host)
        {
            try
            {
                using (HttpContent httpcontent = new StringContent(postdata))
                {
                    httpcontent.Headers.Add("slovetoken", _config.SloveToken);
                    if (_current_node != null)
                    {
                        httpcontent.Headers.Add("fromnode", _current_node?.host);
                    }
                    if (_current_master != null)
                    {
                        httpcontent.Headers.Add("masternode", _current_master?.host);
                    }
                    httpcontent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json;chartset=utf-8");
                    var client = _httpClientFactory.CreateClient();
                    client.Timeout = TimeSpan.FromSeconds(4);
                    client.DefaultRequestHeaders.Referrer = new Uri(url);
                    var response = await client.PostAsync(url, httpcontent);
                    var backstream = await response.Content.ReadAsStringAsync();
                    if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.NoContent && response.StatusCode != HttpStatusCode.Created)
                    {
                        _logger.LogError($"URL:{url} CODE:{response.StatusCode} POST:{postdata} BACK:{backstream}");
                    }
                    return ((int)response.StatusCode, backstream);
                }
            }
            catch (Exception exl)
            {
                _logger.LogError("line.1619 " + exl.Message);
                _logger.LogError(exl.StackTrace);
                return (500, exl.Message);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {

            //离开集合
            _leave().Wait();

            if (_timer != null)
            {
                _timer.Stop();
                _timer.Dispose();
            }
            //Task.CompletedTask;
        }

        #endregion

        //是否要压入队列 
        //统计数据打印 某一个消息的次数！
    }







}
